﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace test4_1._1
{
    class Program
    {
        static void Main(string[] args)
        {

            double[][] result1 = LogTable.CreateFunctionTable();//(已修复)CS0176:无法使用实例引用来访问成员；请改用类型名来限定它
            double[][] result2 = LogTable.CreateFunctionTable2();
            double[][] result3 = LogTable.CreateFunctionTable3();
            Console.WriteLine("常用对数表：");
            Console.Write("      ");
            for (int a = 0; a <= 9; a++)//输出列号
            {
                Console.Write("{0}       ", a);
            }
            Console.WriteLine();
            double k = 1.0;
            for (int i = 0; i < 90; i++)
            {
                Console.Write("{0:F2}: ", k);//在每一行之前输出行号
                for (int j = 0; j < 10; j++)//循环输出行，每一行被计算的x的个位与十分位相同，百分位依次加1
                {
                    Console.Write("{0:F4}  ", result1[i][j]);//{0:F4}表示保留4位小数，末位四舍五入
                }
                Console.WriteLine();
                k = k + 0.1;
            }
            Console.WriteLine("自然对数表：");
            Console.Write("      ");
            for (int a = 0; a <= 9; a++)//输出列号
            {
                Console.Write("{0}       ", a);
            }
            Console.WriteLine();
            k = 1.0;
            for (int i = 0; i < 90; i++)
            {
                Console.Write("{0:F2}: ", k);//在每一行之前输出行号
                for (int j = 0; j < 10; j++)//循环输出行，每一行被计算的x的个位与十分位相同，百分位依次加1
                {
                    Console.Write("{0:F4}  ", result2[i][j]);//{0:F4}表示保留4位小数，末位四舍五入
                }
                Console.WriteLine();
                k = k + 0.1;
            }

            Console.WriteLine("反对数表：");
            Console.Write("      ");
            for (int a = 0; a <= 9; a++)//输出列号
            {
                Console.Write("{0}        ", a);
            }
            Console.WriteLine();
            k = 0.0;
            for (int i = 0; i < 90; i++)
            {
                Console.Write("{0:F2}: ", k);//在每一行之前输出行号
                for (int j = 0; j < 10; j++)//循环输出行，每一行被计算的x的个位与十分位相同，百分位依次加1
                {
                    Console.Write("{0:F3}    ", result3[i][j]);//{0:F4}表示保留4位小数，末位四舍五入
                }
                Console.WriteLine();
                k = k + 0.1;
            }
            Console.ReadLine();
        }
    }

    delegate double OneFunction(double x);

    class LogTable
    {
        public static double[] Apply(double[] arr, OneFunction function)//注意此处需返回double[]
        {
            double[] result = new double[arr.Length];
            for (int i = 0; i < arr.Length; i++)
            {
                result[i] = function(arr[i]);//将OneFunction委托所封装的方法应用到arr数组中的每一个元素，并将结果赋给新的数组
            }
            return result;
        }

        public static T[] Apply1<T>(T[] arr, Func<T, T> function)//使用泛型委托Func实现Apply函数
        {
            T[] result = new T[arr.Length];
            for (int i = 0; i < arr.Length; i++)
            {
                result[i] = function(arr[i]);
            }
            return result;
        }//定义了一个泛型方法Apply1，它接受一个泛型数组和Func委托对象作为参数，并返回一个泛型数组


        //错误示例：这样操作会改变原始数组arr的值，导致原始数组的值改变后传入了错误的值，应定义一个新的数组result来存储函数应用的结果
        //public static double[] Apply(double[] arr, OneFunction function)//注意此处需返回double[]
        //{
        //    for (int i = 0; i < arr.Length; i++)
        //    {
        //        arr[i] = function(arr[i]);
        //    }
        //    return arr;
        //}


        /// <summary>
        /// 常用对数表（底数为10）
        /// </summary>
        /// <returns></returns>
        public static double[][] CreateFunctionTable()//静态方法，需要直接使用类名，无需创建实例
        {
            double[][] result = new double[90][];
            double[] target = new double[10] { 1, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09 };
            for (int i = 0; i < 90; i++)
            {
                result[i] = Apply(target, x => Math.Log10(x));//在Lambda表达式中的参数x被隐式定义
                target = Apply1(target, x => x + 0.1);//target数组中的每个元素都被加0.1
            }//分别使用了自定义委托与泛型委托实现
            return result;
        }

        /// <summary>
        /// 自然对数表（底数为e）
        /// </summary>
        /// <returns></returns>
        public static double[][] CreateFunctionTable2()//静态方法，需要直接使用类名，无需创建实例
        {
            double[][] result = new double[90][];
            double[] target = new double[10] { 1, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09 };
            for (int i = 0; i < 90; i++)
            {
                result[i] = Apply(target, x => Math.Log(x));//在Lambda表达式中的参数x被隐式定义
                target = Apply(target, x => x + 0.1);//target数组中的每个元素都被加0.1
            }
            return result;
        }

        /// <summary>
        /// 反对数表（底数为10）
        /// </summary>
        /// <returns></returns>
        public static double[][] CreateFunctionTable3()//静态方法，需要直接使用类名，无需创建实例
        {
            double[][] result = new double[90][];
            double[] target = new double[10] { 0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09 };
            for (int i = 0; i < 90; i++)
            {
                result[i] = Apply(target, x => Math.Pow(10, x));//在Lambda表达式中的参数x被隐式定义
                target = Apply(target, x => x + 0.1);//target数组中的每个元素都被加0.1
            }
            return result;
        }
    }

}
